home *** CD-ROM | disk | FTP | other *** search
/ Magnum One / Magnum One (Mid-American Digital) (Disc Manufacturing).iso / d20 / sqsh_100.arc / SSTAT.ARC / SSTAT.C < prev    next >
C/C++ Source or Header  |  1991-11-06  |  9KB  |  421 lines

  1. /*#define DEBUG*/
  2.  
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <stdlib.h>
  6. #include <io.h>
  7. #include <fcntl.h>
  8. #include "prog.h"
  9. #include "sstat.h"
  10. #include "sstatp.h"
  11.  
  12.  
  13. static int near MatchNN(NETADDR *n1, NETADDR *n2)
  14. {
  15.   return (n1->zone==n2->zone &&
  16.           n1->net ==n2->net  &&
  17.           n1->node==n2->node &&
  18.           n1->point==n2->point);
  19. }
  20.  
  21.  
  22.  
  23. static int near DoThisArea(char *tag)
  24. {
  25.   struct _arealist *al;
  26.   
  27.   for (al=sc.area; al; al=al->next)
  28.     if (eqstri(tag, al->tag))
  29.       return TRUE;
  30.     
  31.   return FALSE;
  32. }
  33.  
  34. static int near DoThisNode(NETADDR *n)
  35. {
  36.   struct _nodelist *nl;
  37.   
  38.   for (nl=sc.node; nl; nl=nl->next)
  39.     if (MatchNN(&nl->n, n))
  40.       return TRUE;
  41.     
  42.   return FALSE;
  43. }
  44.  
  45.  
  46.  
  47. /* Read all of the specified nodes in from the SQUISH.STA stats file */
  48.  
  49. static void near ReadArea(int fd, struct _ahlist *al, struct _areahdr *ah)
  50. {
  51.   struct _nodehdr nh;
  52.   struct _stlist *sl;
  53.   struct _nodtot *nt;
  54.  
  55.  
  56.   al->in_msgs += ah->in_msgs;
  57.   al->in_bytes += ah->in_bytes/1024;
  58.  
  59.   while (ah->n_nodes--)
  60.   {
  61.     if (read(fd, (char *)&nh, sizeof(struct _nodehdr)) != 
  62.                                             sizeof(struct _nodehdr))
  63.       return;
  64.     
  65.     #ifdef DEBUG
  66.     printf("    Node         = %s\n", Address(&nh.node));
  67.     printf("        OutMsgs  = %ld\n", nh.out_msgs);
  68.     printf("        OutBytes = %ld\n", nh.out_bytes);
  69.     #endif
  70.  
  71.     /* Only process the specified nodes */
  72.       
  73.     if (! DoThisNode(&nh.node))
  74.       continue;
  75.     
  76.     for (sl=al->slist; sl; sl=sl->next)
  77.       if (MatchNN(&sl->node, &nh.node))
  78.         break;
  79.       
  80.     if (sl==NULL)
  81.     {
  82.       sl=smalloc(sizeof(struct _stlist));
  83.       
  84.       sl->next=al->slist;
  85.       al->slist=sl;
  86.     }
  87.  
  88.     /* Make sure that this node is already in the llist of node totals */
  89.  
  90.     for (nt=nodtot; nt; nt=nt->next)
  91.       if (MatchNN(&nt->node, &nh.node))
  92.         break;
  93.  
  94.     /* Not there, so add it */
  95.  
  96.     if (nt==NULL)
  97.     {
  98.       nt=smalloc(sizeof(struct _nodtot));
  99.  
  100.       nt->node=nh.node;
  101.  
  102.       nt->next=nodtot;
  103.       nodtot=nt;
  104.     }
  105.     
  106.     sl->node=nh.node;
  107.     sl->out_msgs += nh.out_msgs;
  108.     sl->out_bytes += nh.out_bytes/1024;
  109.   }
  110. }
  111.  
  112.  
  113.  
  114.  
  115.  
  116. static void near ParseStats(int fd)
  117. {
  118.   struct _areahdr ah;
  119.   struct _ahlist *al;
  120.  
  121.   while (read(fd, (char *)&ah, sizeof(struct _areahdr))==
  122.                                                 sizeof(struct _areahdr))
  123.   {
  124.     #ifdef DEBUG
  125.     printf("AREA     = %s\n", ah.tag);
  126.     printf(" InMsgs  = %ld\n", ah.in_msgs);
  127.     printf(" InBytes = %ld\n", ah.in_bytes);
  128.     printf(" n_nodes = %d\n", ah.n_nodes);
  129.     #endif
  130.  
  131.     for (al=ahlist; al; al=al->next)
  132.       if (eqstri(ah.tag, al->tag))
  133.         break;
  134.  
  135.     /* This area not found */
  136.  
  137.     if (al==NULL)
  138.     {
  139.       al=smalloc(sizeof(struct _ahlist));
  140.  
  141.       strcpy(al->tag, ah.tag);
  142.  
  143.       al->next=ahlist;
  144.       ahlist=al;
  145.     }
  146.  
  147.     ReadArea(fd, al, &ah);
  148.   }
  149. }
  150.  
  151.  
  152.  
  153.  
  154.  
  155. static int near Percent1(dword a, dword b)
  156. {
  157.   return (int)(a*100L/b);
  158. }
  159.  
  160.  
  161.  
  162.  
  163. static int near Percent2(dword a, dword b)
  164. {
  165.   return (int)((a*10000L/b) % 100L);
  166. }
  167.  
  168. #define Percent(a, b) Percent1(a,b), Percent2(a,b)
  169.  
  170.  
  171.  
  172.  
  173. static void near CalcTotals(dword *total_in_bytes, dword *total_in_msgs)
  174. {
  175.   struct _ahlist *al;
  176.   struct _stlist *sl;
  177.  
  178.   *total_in_bytes=*total_in_msgs=0;
  179.  
  180.   for (al=ahlist; al; al=al->next)
  181.   {
  182.     if (! DoThisArea(al->tag))
  183.       continue;
  184.     
  185.     al->total_out_bytes=al->total_out_msgs=0;
  186.  
  187.     for (sl=al->slist; sl; sl=sl->next)
  188.     {
  189.       al->total_out_bytes += sl->out_bytes;
  190.       al->total_out_msgs  += sl->out_msgs;
  191.     }
  192.  
  193.     if (al->total_out_bytes==0 && al->total_out_msgs==0)
  194.       continue;
  195.  
  196.     *total_in_bytes += al->in_bytes;
  197.     *total_in_msgs  += al->in_msgs;
  198.   }
  199. }
  200.  
  201.  
  202.  
  203.  
  204. static void near CalculateStats(dword total_in_bytes, dword total_in_msgs)
  205. {
  206.   struct _ahlist *al;
  207.   struct _stlist *sl;
  208.   struct _nodtot *nt;
  209.  
  210.   for (al=ahlist; al; al=al->next)
  211.   {
  212.     if (! DoThisArea(al->tag))
  213.       continue;
  214.  
  215.     /* Don't log areas with no output */
  216.  
  217.     printf("\nArea %s\n", al->tag);
  218.  
  219.     if (total_in_bytes==0 || total_in_msgs==0 ||
  220.         al->total_out_bytes==0 || al->total_out_msgs==0)
  221.     {
  222.       printf("   NO SIGNIFICANT TRAFFIC\n");
  223.       continue;
  224.     }
  225.  
  226.     printf("  KBYTES IN: %8ld (%02d.%02d%% of total bytes in)\n",
  227.            al->in_bytes,
  228.            (int)(al->in_bytes*100/total_in_bytes),
  229.            (int)((al->in_bytes*10000/total_in_bytes) % 100));
  230.  
  231.     printf("  MSGS IN:   %8ld (%02d.%02d%% of total msgs in)\n",
  232.            al->in_msgs,
  233.            (int)(al->in_msgs*100/total_in_msgs),
  234.            (int)((al->in_msgs*10000/total_in_msgs) % 100));
  235.  
  236.     printf("  KBYTES OUT:%8ld\n\n", al->total_out_bytes);
  237.  
  238.  
  239.     printf("   Node            KByteOut MsgOut %%KBytes %%  Msgs %%TKBCst %% TMCst\n");
  240.     printf("   --------------- -------- ------ ------- ------- ------- -------\n");
  241.  
  242.     for (sl=al->slist; sl; sl=sl->next)
  243.     {
  244.       double area_percent_bytes, area_percent_msgs;
  245.  
  246.       area_percent_bytes=((double)sl->out_bytes/(double)al->total_out_bytes)*
  247.                          ((double)al->in_bytes /(double)total_in_bytes)*
  248.                           (double)100;
  249.  
  250.       area_percent_msgs =((double)sl->out_msgs/(double)al->total_out_msgs)*
  251.                          ((double)al->in_msgs /(double)total_in_msgs)*
  252.                           (double)100;
  253.  
  254.       printf("   %-15s %8ld %6ld %3d.%02d%% %3d.%02d%% %6.02f%% %6.02f%%\n",
  255.              Address(&sl->node),
  256.              sl->out_bytes,
  257.              sl->out_msgs,
  258.              Percent(sl->out_bytes, al->total_out_bytes),
  259.              Percent(sl->out_msgs,  al->total_out_msgs),
  260.              area_percent_bytes,
  261.              area_percent_msgs);
  262.  
  263.       for (nt=nodtot; nt; nt=nt->next)
  264.         if (MatchNN(&nt->node, &sl->node))
  265.         {
  266.           nt->total_percent_bytes += area_percent_bytes;
  267.           nt->total_percent_msgs  += area_percent_msgs;
  268.           break;
  269.         }
  270.     }
  271.   }
  272.  
  273.   printf("\nNODE TOTALS:\n\n");
  274.  
  275.   printf("   Node             %Bytes % Msgs\n");
  276.   printf("   ---------------- ------ ------\n");
  277.  
  278.   for (nt=nodtot; nt; nt=nt->next)
  279.   {
  280.     printf("   %-15s  %05.02f%% %05.02f%%\n",
  281.            Address(&nt->node),
  282.            nt->total_percent_bytes,
  283.            nt->total_percent_msgs);
  284.   }
  285.  
  286. }
  287.  
  288.  
  289.  
  290.  
  291.  
  292. static void near ParseConfigLine(char *line)
  293. {
  294.   static char *cfgdelim=" \t\n\r,";
  295.   char *s;
  296.  
  297.   /* Strip off any comments */
  298.   
  299.   if ((s=strchr(line, ';')) != NULL)
  300.     *s='\0';
  301.  
  302.  
  303.   /* Grab a word from the config */
  304.   
  305.   s=strtok(line, cfgdelim);
  306.   
  307.   /* Nodes to track */
  308.   
  309.   if (s==NULL)
  310.     return;
  311.  
  312.   if (eqstri(s, "track"))
  313.   {
  314.     struct _nodelist *node;
  315.     NETADDR last;
  316.   
  317.     memset(&last, '\0', sizeof(NETADDR));
  318.  
  319.  
  320.     /* Parse all net/node numbers off this line */
  321.     
  322.     while ((s=strtok(NULL, cfgdelim)) != NULL)
  323.     {
  324.       node=smalloc(sizeof(struct _nodelist));
  325.  
  326.       node->n=last;
  327.       
  328.       ParseNN(s, &node->n.zone, &node->n.net,
  329.               &node->n.node, &node->n.point, FALSE);
  330.       
  331.       last=node->n;
  332.  
  333.       /* Append to linked list */
  334.       
  335.       node->next=sc.node;
  336.       sc.node=node;
  337.     }
  338.   }
  339.   else if (eqstri(s, "area"))
  340.   {
  341.     struct _arealist *area;
  342.     
  343.     while ((s=strtok(NULL, cfgdelim)) != NULL)
  344.     {
  345.       area=smalloc(sizeof(struct _arealist));
  346.       
  347.       area->tag=sstrdup(s);
  348.       
  349.       area->next=sc.area;
  350.       sc.area=area;
  351.     }
  352.   }
  353.   else
  354.   {
  355.     printf("Invalid keyword in config file: `%s'\n", s);
  356.   }
  357. }
  358.  
  359.  
  360.  
  361.  
  362.  
  363. static void near ParseConfig(char *cfg)
  364. {
  365.   FILE *fp;
  366.   char line[PATHLEN];
  367.   
  368.   sc.node=NULL;
  369.   sc.area=NULL;
  370.   
  371.   if (cfg==NULL)
  372.     cfg="SSTAT.CFG";
  373.   
  374.   if ((fp=fopen(cfg, "r"))==NULL)
  375.   {
  376.     printf("Error opening `%s'!\n", cfg);
  377.     exit(1);
  378.   }
  379.   
  380.   while (fgets(line, PATHLEN, fp))
  381.     ParseConfigLine(line);
  382.   
  383.   fclose(fp);
  384. }
  385.  
  386.  
  387.  
  388.  
  389.  
  390. int _stdc main(int argc, char *argv[])
  391. {
  392.   dword total_in_bytes, total_in_msgs;
  393.   int fd;
  394.  
  395.   NW(argc);
  396.   NW(argv);
  397.   
  398.   ParseConfig(argv[1]);
  399.  
  400.   if ((fd=open("SQUISH.STA", O_RDONLY | O_BINARY))==-1)
  401.   {
  402.     printf("Error!  No statistics file to read!\n");
  403.     return 1;
  404.   }
  405.  
  406.   ParseStats(fd);
  407.   close(fd);
  408.  
  409.   CalcTotals(&total_in_bytes, &total_in_msgs);
  410.   CalculateStats(total_in_bytes, total_in_msgs);
  411.  
  412.   return 0;
  413. }
  414.  
  415. void _fast NoMem(void)
  416. {
  417.   printf("Ran out of memory!\n");
  418.   exit(1);
  419. }
  420.  
  421.